package com.jade.bss.web.controller;

import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.jade.bss.admin.account.AdminAccount;
import com.jade.bss.admin.account.AdminAccountManager;
import com.jade.bss.admin.grant.GrantManager;
import com.jade.bss.admin.journal.AdminJournal;
import com.jade.bss.admin.permission.PermissionEntry;
import com.jade.bss.admin.principal.SimplePrincipal;
import com.jade.bss.admin.role.RoleEntry;
import com.jade.bss.admin.role.RoleManager;
import com.jade.bss.base.BssConstants;
import com.jade.bss.web.resolver.AdminCapsule;
import com.jade.bss.web.vo.RoleEntryVo;
import com.jade.framework.base.context.ApplicationContextUtils;
import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.criterion.CriterionUtils;
import com.jade.framework.base.criterion.Restrictions;
import com.jade.framework.base.util.PagingList;
import com.jade.framework.base.util.PagingResult;
import com.jade.framework.base.util.ResponseUtils;
import com.jade.journal.JournalEntityManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;

/**
 * 默认的管理账号控制器。
 *
 * @author Daisy
 * @version 1.0 14-10-9 下午11:15
 */
@RestController
@RequestMapping ("/adminAccount")
@Api(value = "管理员账号", description = "管理管理员账号")
public class AdminAccountController
{
    private RoleManager roleManager = ApplicationContextUtils.getBean("bss_roleManager");
    private GrantManager grantManager = ApplicationContextUtils.getBean("bss_grantManager");
    private AdminAccountManager adminAccountManager = ApplicationContextUtils.getBean("bss_adminAccountManager");
    private JournalEntityManager journalEntityManager = ApplicationContextUtils.getBean("system_journalEntityManager");

    //@RequiresAuthentication
    @RequestMapping (value = "/query", method = RequestMethod.GET)
    @RequiresPermissions (value = {"admin:view"})
    @ApiOperation(value = "查询账号", httpMethod = "GET", response = AdminAccount.class)
    public void queryAccount(@ApiParam(value = "关键词") @RequestParam (value = "keyword", required = false) String keyword,
                             @ApiParam(value = "起始值") @RequestParam (value = "offset", defaultValue = "0") int offset,
                             @ApiParam(value = "每页大小") @RequestParam (value = "length",defaultValue = "10") int length,
                             @ApiParam(value = "排序字段") @RequestParam (value = "sort", required = false) String sort,
                             @ApiParam(value = "排序规则", allowableValues = "desc, asc") @RequestParam (value = "order", required = false) String order,
                             @RequestParam (value = "callback", required = false) String callback, HttpServletResponse response)
            throws Exception
    {
        Criteria criteria = new Criteria(offset, length);
        criteria.add(Restrictions.eq("ownerType", BssConstants.OWNER_TYPE_SYSTEM));
        criteria.add(Restrictions.eq("ownerId", BssConstants.OWNER_ID_SYSTEM));
        if (!StringUtils.isBlank(keyword)) {
            criteria.add(Restrictions.or(Restrictions.like("name", keyword), Restrictions.like("realName", keyword),
                    Restrictions.like("mobile", keyword), Restrictions.like("phone", keyword),
                    Restrictions.like("email", keyword)));
        }
        CriterionUtils.addOrder(criteria, sort, order, "id");
        PagingList<AdminAccount> accounts = adminAccountManager.queryAdmin(criteria);
        Map<Integer, String> roleMap = loadRoles(accounts);
//        AjaxResult result = ControllerUtils.getAjaxResult(accounts, new AdminAccount[accounts.size()], callback);
        PagingResult result = PagingResult.getResult(accounts, accounts.getTotalCount());
        result.setCallback(callback);
        if (roleMap != null && roleMap.size() > 0) {
            result.setParam("roles", roleMap);
        }
        result.setOffset(offset);
        result.setPageSize(length);
        ResponseUtils.writeSuccessPagingResult(response, result);
    }

    @ResponseBody
    //@RequiresAuthentication
    @RequestMapping (value = "/add", method = RequestMethod.POST)
    @RequiresPermissions (value = {"admin:create"})
    @ApiOperation(value = "增加账号", httpMethod = "POST")
    public void addAccount(@ApiParam(value = "账号对象", required = true) @RequestBody AdminAccount admin,
                           @ApiParam(value = "角色id") @RequestParam (value = "roleId", required = false) int[] roleIds,
                           AdminCapsule capsule, HttpServletResponse response)
            throws Exception
    {
        admin.setCreationDate(new Date());
        admin.setOwnerId(String.valueOf(BssConstants.OWNER_ID_SYSTEM));
        admin.setOwnerType(BssConstants.OWNER_TYPE_SYSTEM);
        adminAccountManager.addAdmin(admin);
        SimplePrincipal principal = new SimplePrincipal();
        principal.setName(String.valueOf(admin.getId()));
        principal.setType(SimplePrincipal.TYPE_ADMIN);
        if (roleIds != null && roleIds.length > 0) {
            grantManager.grantRoles(principal, roleIds);
        }
        ResponseUtils.writeSuccessResult(response);
    }

    @ResponseBody
    @RequiresAuthentication
    @RequiresPermissions (value = {"admin:remove"})
    @RequestMapping (value = "/remove/{id}", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除帐户", httpMethod = "DELETE")
    public void removeAccount(@ApiParam(value = "帐户id") @PathVariable ("id") int[] ids, HttpServletResponse response)
            throws Exception
    {
        adminAccountManager.removeAdmin(ids);
        ResponseUtils.writeSuccessResult(response);
    }

    @ResponseBody
    @RequestMapping ("/get/{id}")
    @ApiOperation(value = "获取帐户", httpMethod = "GET", response = AdminAccount.class)
    public void getAccount(@ApiParam(value = "帐户id")@PathVariable int id,HttpServletResponse response)
            throws Exception
    {
        AdminAccount admin = adminAccountManager.getAdmin(id);
        ResponseUtils.writeSuccessResult(response,admin);
    }

    @ResponseBody
    @RequiresAuthentication
    @RequestMapping (value = "/myAccount", method = RequestMethod.GET)
    @ApiOperation(value = "获取帐户", httpMethod = "GET", response = AdminAccount.class)
    public void myAccount(AdminCapsule capsule,HttpServletResponse response)
            throws Exception
    {
        AdminAccount adminAccount = capsule.unwrap();
        AdminAccount dataAccount = adminAccountManager.getAdmin(adminAccount.getId());
        ResponseUtils.writeSuccessResult(response,dataAccount);
    }

    @ResponseBody
    @RequiresAuthentication
    @RequestMapping (value = "/edit", method = RequestMethod.PUT)
    @RequiresPermissions (value = {"admin:update"})
    @ApiOperation(value = "编辑帐户", httpMethod = "PUT")
    public void editAccount(@ApiParam(value = "账号对象") @RequestBody AdminAccount admin, HttpServletResponse response)
            throws Exception
    {
        adminAccountManager.updateAdmin(admin);
        ResponseUtils.writeSuccessResult(response);
    }

    @ResponseBody
    @RequiresAuthentication
    @RequestMapping (value = "/resetPwd", method = RequestMethod.POST)
    @RequiresPermissions (value = {"admin:reset_pwd"})
    @ApiOperation(value = "修改密码", httpMethod = "POST")
    public void resetPwd(@ApiParam(value = "账号id") @RequestParam ("id") int id,
                         @ApiParam(value = "帐户密码") @RequestParam ("password") String password,
                         HttpServletResponse response)
            throws Exception
    {
        adminAccountManager.resetPassword(id, password);
        ResponseUtils.writeSuccessResult(response);
    }

    protected Map<Integer, String> loadRoles(List<AdminAccount> adminList)
            throws Exception
    {
        HashMap<Integer, String> result = new HashMap<Integer, String>();
        if (adminList != null) {
            for (AdminAccount admin : adminList) {
                SimplePrincipal principal = new SimplePrincipal();
                principal.setName(String.valueOf(admin.getId()));
                principal.setType(SimplePrincipal.TYPE_ADMIN);

                List<RoleEntry> adminsRoleList = grantManager.getRole(principal);
                if (adminsRoleList != null && adminsRoleList.size() > 0) {
                    StringBuilder sb = new StringBuilder();
                    for (RoleEntry role : adminsRoleList) {
                        if (role != null) {
                            sb.append(",").append(role.getName());
                        }
                    }
                    result.put(admin.getId(), sb.toString().substring(1));
                }
            }
        }

        return result;
    }

    @ResponseBody
    @RequiresAuthentication
    @RequestMapping (value = "/toGrantAccount/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "获取授权信息", httpMethod = "GET")
    public void toGrantAccount(@ApiParam(value = "帐户标识") @PathVariable int id,HttpServletResponse response)
            throws Exception
    {
        AdminAccount admin = adminAccountManager.getAdmin(id);
        SimplePrincipal principal = new SimplePrincipal();
        principal.setName(String.valueOf(admin.getId()));
        principal.setType(SimplePrincipal.TYPE_ADMIN);
        List<RoleEntry> adminRoles = grantManager.getRole(principal);
        List<RoleEntry> roles = roleManager.listRole(admin.getType());
        List<RoleEntryVo> roleEntryVos = new ArrayList<RoleEntryVo>();
        if (adminRoles != null) {
            for (RoleEntry entry : roles) {
                RoleEntryVo roleEntryVo = new RoleEntryVo();
                roleEntryVo.setRoleId(entry.getId());
                roleEntryVo.setRoleName(entry.getName());
                for (RoleEntry roleEntry : adminRoles) {
                    if (roleEntry.getId() == entry.getId()) {
                        roleEntryVo.setChecked(true);
                        break;
                    }
                }
                roleEntryVos.add(roleEntryVo);
            }
        }
        ResponseUtils.writeSuccessResult(response,roleEntryVos);
    }

    @ResponseBody
    @RequiresAuthentication
    @RequestMapping (value = "/grantAdmin", method = RequestMethod.GET)
    @RequiresPermissions (value = {"admin:grant"})
    @ApiOperation(value = "帐户授权", httpMethod = "GET")
    public void grantAdmin(@ApiParam(value = "帐户编号") @RequestParam ("id") String adminId,
                           @ApiParam(value = "角色编号") @RequestParam (value = "roleId", required = false) int[] roleIds,
                           HttpServletResponse response)
            throws Exception
    {
        SimplePrincipal principal = new SimplePrincipal();
        principal.setName(adminId);
        principal.setType(SimplePrincipal.TYPE_ADMIN);
        grantManager.revokeRoles(principal);
        if (roleIds != null && roleIds.length > 0) {
            grantManager.grantRoles(principal, roleIds);
        }
        ResponseUtils.writeSuccessResult(response);
    }

    @RequiresAuthentication
    @RequestMapping (value = "/getPermissions", method = RequestMethod.GET)
    @ApiOperation(value = "获取自身帐户权限", httpMethod = "GET")
    public void getAdminPermissions(AdminCapsule adminCapsule,HttpServletResponse response)
           throws Exception
    {
        AdminAccount account = adminCapsule.unwrap();
        List<String> permissions = new ArrayList<String>();
        if(account.getId()==1)
        {
            permissions.add(BssConstants.OWNER_TYPE_ADMIN);
        }
        else
        {
            SimplePrincipal principal = new SimplePrincipal();
            principal.setName(String.valueOf(account.getId()));
            principal.setType(SimplePrincipal.TYPE_ADMIN);
            List<PermissionEntry> perList = grantManager.getPermissions(principal);
            if (perList != null) {
                for (PermissionEntry perEntry : perList) {
                    permissions.add(perEntry.getName());
                }
            }
        }
        ResponseUtils.writeSuccessResult(response,permissions);
    }

    @ResponseBody
    @RequiresAuthentication
    @RequestMapping (value = "/modifyMyPassword", method = RequestMethod.PUT)
    @ApiOperation(value = "修改自身帐户密码", httpMethod = "PUT")
    public void modifyMyPassword(@ApiParam(value = "旧密码") @RequestParam ("oldPassword") String oldPassword,
                                 @ApiParam(value = "新密码") @RequestParam ("password") String password, HttpServletResponse response,
                                 AdminCapsule capsule)
            throws Exception
    {
        AdminAccount account = capsule.unwrap();
        adminAccountManager.modifyPassword(account.getId(), oldPassword, password);
        ResponseUtils.writeSuccessResult(response);
    }

    @ResponseBody
    @RequiresAuthentication
    @RequestMapping (value = "/editMyAccount", method = RequestMethod.PUT)
    @RequiresPermissions (value = {"admin:update"})
    @ApiOperation(value = "修改自身帐户信息", httpMethod = "PUT")
    public void editMyAccount(@ApiParam(value = "帐户信息") @RequestBody AdminAccount admin, HttpServletResponse response,
                              AdminCapsule capsule)
            throws Exception
    {
        AdminAccount account = capsule.unwrap();
        admin.setId(account.getId());
        admin.setStatus(account.getStatus());
        adminAccountManager.updateAdmin(admin);
        ResponseUtils.writeSuccessResult(response);
    }

    @ResponseBody
    @RequiresAuthentication
    @RequestMapping (value = "/list", method = RequestMethod.GET)
    @ApiOperation(value = "获取帐户列表", httpMethod = "GET")
    public void list(@RequestParam (value = "ownerId", required = false) String ownerId,
                                   @RequestParam (value = "ownerType", required = false) String ownerType, HttpServletResponse response)
            throws Exception
    {
        Criteria criteria = new Criteria(-1, -1);
        if (StringUtils.isNotBlank(ownerId)) {
            criteria.add(Restrictions.eq("ownerId", ownerId));
        }
        if (StringUtils.isNotBlank(ownerType)) {
            criteria.add(Restrictions.eq("ownerType", ownerType));
        }
        PagingList list = adminAccountManager.queryAdmin(criteria);
        ResponseUtils.writeSuccessPagingResult(response, PagingResult.getResult(list));
    }

    @ResponseBody
    @RequiresAuthentication
    @RequestMapping (value = "/listAdmLog", method = RequestMethod.GET)
    @ApiOperation(value = "获取帐户日志", httpMethod = "GET")
    public void listAccountLog(@ApiParam(value = "关键字") @RequestParam (value = "keyword", required = false) String keyword,
                                     @ApiParam(value = "起始值") @RequestParam (value = "offset") int offset,
                                     @ApiParam(value = "每页大小") @RequestParam (value = "length") int length,
                                     @ApiParam(value = "排序字段") @RequestParam (value = "sort", required = false) String sort,
                                     @ApiParam(value = "排序规则", allowableValues = "desc, asc") @RequestParam (value = "order", required = false) String order,
                                     @RequestParam (value = "callback", required = false) String callback,
                                     HttpServletResponse response)
            throws Exception
    {
        Criteria criteria = new Criteria(offset, length);
        if (!StringUtils.isBlank(keyword)) {
            criteria.add(Restrictions.or(Restrictions.like("adminName", keyword),
                    Restrictions.like("clientAddress", keyword)));
        }

        PagingList<AdminJournal> list = journalEntityManager.queryEntity(AdminJournal.class, criteria);
        PagingResult result = PagingResult.getResult(list);
        result.setCallback(callback);
        ResponseUtils.writeSuccessResult(response, result);
    }
}